package cn.edu.swu.miniwebsvr.core;

import java.io.InputStream;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class HttpParser {

    public static Parameter parse(InputStream inputStream) throws IOException {
        Parameter parameter = new Parameter();
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));

        // TODO: [222024321072047/李明燊]
        // 1. 读取并解析 HTTP 请求行 (e.g., GET /path?param=value HTTP/1.1)
        String requestLine = reader.readLine();
        if (requestLine == null || requestLine.isEmpty()) {
            return null; // 空请求
        }

        System.out.println("请求行: " + requestLine);

        // 解析请求行
        String[] requestParts = requestLine.split(" ");
        if (requestParts.length < 3) {
            return null; // 无效的请求行
        }

        String method = requestParts[0];
        String fullUrl = requestParts[1];
        String httpVersion = requestParts[2];

        parameter.setMethod(method);

        // 分离URL和查询参数
        String url;
        String queryString = null;
        int questionMarkIndex = fullUrl.indexOf('?');
        if (questionMarkIndex != -1) {
            url = fullUrl.substring(0, questionMarkIndex);
            queryString = fullUrl.substring(questionMarkIndex + 1);
        } else {
            url = fullUrl;
        }

        parameter.setUrl(url);

        // 解析URL参数
        if (queryString != null) {
            Map<String, String> urlParams = parseQueryString(queryString);
            for (Map.Entry<String, String> entry : urlParams.entrySet()) {
                parameter.addUrlParam(entry.getKey(), entry.getValue());
            }
        }

        // 2. 循环读取并解析所有 HTTP 请求头 (e.g., Host: localhost:8080)
        String headerLine;
        int contentLength = 0;
        String contentType = null;

        while ((headerLine = reader.readLine()) != null) {
            if (headerLine.isEmpty()) {
                break; // 空行表示请求头结束
            }

            int colonIndex = headerLine.indexOf(':');
            if (colonIndex > 0) {
                String headerName = headerLine.substring(0, colonIndex).trim();
                String headerValue = headerLine.substring(colonIndex + 1).trim();

                parameter.addHeader(headerName, headerValue);

                // 记录重要的请求头信息
                if ("Content-Length".equalsIgnoreCase(headerName)) {
                    try {
                        contentLength = Integer.parseInt(headerValue);
                    } catch (NumberFormatException e) {
                        System.err.println("无效的Content-Length: " + headerValue);
                    }
                } else if ("Content-Type".equalsIgnoreCase(headerName)) {
                    contentType = headerValue;
                }
            }
        }

        // 3. 根据请求方法 (Method) 和请求头 (Content-Length, Content-Type) 判断并读取请求体
        if ("POST".equalsIgnoreCase(method) && contentLength > 0) {
            char[] bodyChars = new char[contentLength];
            int bytesRead = reader.read(bodyChars, 0, contentLength);

            if (bytesRead > 0) {
                String requestBody = new String(bodyChars, 0, bytesRead);
                System.out.println("请求体: " + requestBody);

                // 解析请求体参数
                if (contentType != null && contentType.contains("application/x-www-form-urlencoded")) {
                    Map<String, String> bodyParams = parseQueryString(requestBody);
                    for (Map.Entry<String, String> entry : bodyParams.entrySet()) {
                        parameter.addBodyParam(entry.getKey(), entry.getValue());
                    }
                }
            }
        }

        return parameter;
    }

    // TODO: [222024321072047/李明燊] 可以添加辅助方法来简化字符串解析和 URL 解码

    /**
     * 解析查询字符串（URL参数或POST表单数据）
     * @param queryString 查询字符串，格式为 key1=value1&key2=value2
     * @return 参数映射
     */
    private static Map<String, String> parseQueryString(String queryString) {
        Map<String, String> params = new HashMap<>();

        if (queryString == null || queryString.isEmpty()) {
            return params;
        }

        String[] pairs = queryString.split("&");
        for (String pair : pairs) {
            int equalsIndex = pair.indexOf('=');
            if (equalsIndex > 0) {
                try {
                    String key = URLDecoder.decode(pair.substring(0, equalsIndex), StandardCharsets.UTF_8.name());
                    String value = URLDecoder.decode(pair.substring(equalsIndex + 1), StandardCharsets.UTF_8.name());
                    params.put(key, value);
                } catch (Exception e) {
                    System.err.println("解析参数失败: " + pair);
                }
            } else if (!pair.isEmpty()) {
                // 只有key没有value的情况
                try {
                    String key = URLDecoder.decode(pair, StandardCharsets.UTF_8.name());
                    params.put(key, "");
                } catch (Exception e) {
                    System.err.println("解析参数失败: " + pair);
                }
            }
        }

        return params;
    }

    /**
     * URL解码辅助方法
     * @param encoded 编码的字符串
     * @return 解码后的字符串
     */
    private static String urlDecode(String encoded) {
        try {
            return URLDecoder.decode(encoded, StandardCharsets.UTF_8.name());
        } catch (Exception e) {
            System.err.println("URL解码失败: " + encoded);
            return encoded;
        }
    }

    /**
     * 从完整的URL中提取路径部分（去除查询参数）
     * @param fullUrl 完整的URL
     * @return 路径部分
     */
    private static String extractPath(String fullUrl) {
        int questionMarkIndex = fullUrl.indexOf('?');
        if (questionMarkIndex != -1) {
            return fullUrl.substring(0, questionMarkIndex);
        }
        return fullUrl;
    }

    /**
     * 从完整的URL中提取查询字符串部分
     * @param fullUrl 完整的URL
     * @return 查询字符串部分，如果没有则返回null
     */
    private static String extractQueryString(String fullUrl) {
        int questionMarkIndex = fullUrl.indexOf('?');
        if (questionMarkIndex != -1) {
            return fullUrl.substring(questionMarkIndex + 1);
        }
        return null;
    }

}
